﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;

namespace Pfz.WpfControls
{
	/// <summary>
	/// Converts a PropertyBinding to and from strings.
	/// </summary>
	public class PropertyBindingConverter:
		TypeConverter
	{
		/// <summary>
		/// Returns true for strings.
		/// </summary>
		public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
		{
			return sourceType == typeof(string);
		}

		/// <summary>
		/// Returns true for strings.
		/// </summary>
		public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
		{
			return destinationType == typeof(string);
		}

		/// <summary>
		/// Gets a property binding from a string.
		/// </summary>
		public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
		{
			string strValue = value as string;
			return ConvertFrom(strValue);
		}

		/// <summary>
		/// Gets a property binding from a string.
		/// Use FullTypeName.PropertyName.
		/// Optionally, use FullTypeName.PropertyName=Display name.
		/// </summary>
		public static PropertyBinding ConvertFrom(string value)
		{
			if (string.IsNullOrEmpty(value))
				return null;

			int pos = value.IndexOf('=');
			string propertyName;
			string displayName = null;

			if (pos == -1)
				propertyName = value;
			else
			{
				propertyName = value.Substring(0, pos);
				displayName = value.Substring(pos + 1);
			}

			PropertyInfo propertyInfo = PropertyInfoConverter.ConvertFrom(propertyName);
			return new PropertyBinding { DisplayName = displayName, Property = propertyInfo };
		}
		
		/// <summary>
		/// Converts a property binding to a string.
		/// </summary>
		public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
		{
			var propertyBound = value as PropertyBinding;
			return ConvertTo(propertyBound);
		}

		/// <summary>
		/// Converts a property binding to a string.
		/// </summary>
		public static string ConvertTo(PropertyBinding propertyBound)
		{
			if (propertyBound == null)
				return null;

			string propertyFullName = PropertyInfoConverter.ConvertTo(propertyBound.Property);
			if (propertyBound.DisplayName == null)
				return propertyFullName;

			return string.Concat
			(
				propertyFullName,
				'=',
				propertyBound.DisplayName
			);
		}
	}
}
